package com.ala4.oxcafe.common.utils;

import jakarta.servlet.http.HttpServletRequest;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;

/**
 * ip地址工具类
 *
 * @author PING
 * @date 2025/8/17 13:58
 */
public class IpAddressUtil {

    // 未知IP常量
    private static final String UNKNOWN = "unknown";
    // 本地地址常量
    private static final String LOCALHOST_IPV4 = "127.0.0.1";
    private static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1";
    // 用于分割多个IP值的分隔符
    private static final String SEPARATOR = ",";

    /**
     * 从HttpServletRequest中获取客户端真实IP地址
     *
     * @param request HttpServletRequest对象
     * @return 真实IP地址
     */
    public static String getClientIp(HttpServletRequest request) {
        // 按优先级检查的请求头列表
        List<String> headers = Arrays.asList(
                "X-Forwarded-For",
                "Proxy-Client-IP",
                "WL-Proxy-Client-IP",
                "HTTP_CLIENT_IP",
                "HTTP_X_FORWARDED_FOR"
        );

        String ip = null;

        // 1. 检查各请求头
        for (String header : headers) {
            ip = request.getHeader(header);
            if (isValidIp(ip)) {
                break;
            }
        }

        // 2. 如果请求头未获取到有效IP，使用getRemoteAddr()
        if (!isValidIp(ip)) {
            ip = request.getRemoteAddr();
        }

        // 3. 处理多个IP的情况（如：X-Forwarded-For: client, proxy1, proxy2）
        if (ip != null && ip.contains(SEPARATOR)) {
            ip = ip.split(SEPARATOR)[0].trim();
        }

        // 4. 处理本地地址
        if (LOCALHOST_IPV6.equals(ip)) {
            ip = LOCALHOST_IPV4;
        }

        return ip == null ? "" : ip;
    }

    /**
     * 验证IP是否有效
     */
    private static boolean isValidIp(String ip) {
        return ip != null &&
                !ip.isEmpty() &&
                !UNKNOWN.equalsIgnoreCase(ip);
    }

    /**
     * 获取服务器本机IP地址
     */
    public static String getServerIp() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return "";
        }
    }

}
